This document regroups the most common assertions you might encounter. For each assertion the library, file and method are indicated along with a short explanation.
Can't register a class as archivable if it doesn't have RTTI
Library: ODFFoundation
File: FWArDyna.cpp
Method: FW_CPrivArchiver::AddNameToLabelPair
Explanation: This error should never happen if you're using native RTTI. If you're using ODF RTTI, then you've forgotten to use the FW_DECLARE_CLASS and FW_DEFINE_CLASS_Mx macros for a class that is being registered as archivable. If you get this error you'll need to figure out which class is being registered for archiving. Since the RTTI isn't available it's not possible to get a class name string, but the four characer class label is available. You'll need to get that information using a debugger.
If an initialize function is registered, a destroy function must be too.
Library: ODFFoundation
File: FWArDyna.cpp
Method: FW_SPrivArcFun::FW_SPrivArcFun
Explanation: Archivable classes can use one-step or two-step initialization. Classes that use one-step initialization use just the "create" function, and do not use an "initialize" function (a NULL pointer is passed to the FW_REGISTER_ARCHIVABLE_CLASS macro). If an initialize function is specified, the class is using two-step initialization. Two-step initialization is a potential source of a resource-leak if an exception is thrown by the initialization function. To prevent this leak, it is necessary to provide a destroy function to destroy the object created by the "create" function. You'll get this assertion if you've provided a non-NULL initialize function but used a NULL destroy function.
Object registry ID was not found in registry
Library: ODFFoundation
File: FWArDyna.cpp
Method: FW_CPrivArchiver::PrivCreateObject
Explanation: If the above assertion fails, the most likely explanation is that some code reading from the stream is not in sync with some code used to create the stream. Another potential problem is that the stream contains a reference to a preregistered runtime object, but for some reason the object wasn't preregistered at runtime. This can be checked by using a debugger. Was the object registry ID that failed lookup a negative ID used to preregister some object? Finally, a last possibility is that the stream of data has been corrupted in some other way.
<Class Label ID> class not registered for archiving. Forgot FW_DO_NOT_DEAD_STRIP ?
Library: ODFFoundation
File: FWArDyna.cpp
Method: ClassLabel_Create
Explanation: A class label ID was encountered in a stream for which no class has been registered. Either you forgot the FW_REGISTER_ARCHIVABLE_CLASS macro, or the translation unit containing it wasn't linked into your part editor. This might happen due to dead-stripping by the linker. You can prevent dead-stripping of archivable classes using the FW_DO_NOT_DEAD_STRIP macro. Call the macro for the archivable class from some function that you know will not be dead-stripped. One such place is your part's Initialize method.
In particular if you create views from resources remember to use FW_DO_NOT_DEAD_STRIP for all the view classes which are not referenced in your code. You call it also in your frame's PostCreateViewFromStream method as ODF samples do.
Note: in the current version you may see the assertion message containing garbled characters between the 4 characters class label and the string "class not registered for archiving...", just ignore these characters.
Following is a correspondance table between class labels and ODF view and menu classes:
Label Class
bscl FW_CPrivBaseScroller
butn FW_CButton
dlog FW_CDialogFrame
edvw FW_CEditView
gpbx FW_CGroupBox
grbx FW_CGrowBox
lbox FW_CListBox
mnit FW_CMenuItem
popm FW_CPopupMenu
pdmn FW_CPullDownMenu
rcls FW_CRadioCluster
sbsc FW_CScrollBarScroller
scbr FW_CScrollBar
sclr FW_CScroller
seit FW_CSeparatorItem
stxt FW_CStaticText
suit FW_CSubMenuItem
suvw FW_CSuperView
tgit FW_CToggleItem
txit FW_CTextItem
No registered archiving functions for class label
Library: ODFFoundation
File: FWArDyna.cpp
Method: FW_CPrivArchiver::PrivCreateObject
Explanation: Under normal circumstances this assertion could only happen if the assertion "<Class Label ID>' class not registered for archiving. Forgot FW_DO_NOT_DEAD_STRIP ?" had already been triggered. If you see this assertion and did not see the "Forgot FW_DO_NOT_DEAD_STRIP?" assertion, please report a bug to the ODF team. See above for more information about this problem.
Attempt to create object from stream with NULL create function
Library: ODFFoundation
File: FWArDyna.cpp
Method: FW_CPrivArchiver::PrivCreateObject
Explanation: The archiving subsystem allows you to pass a NULL pointer in the place of the "create" function parameter. However, if the archiver encounters a class label ID for such a class while reading from a stream then it will be unable to create the object.
Class <className> has already been registered as archivable!
Library: ODFFoundation
File: FWArDyna.cpp
Method: FW_CPrivArchiver::AddNameToLabelPair
Explanation: You probably have used the FW_REGISTER_ARCHIVABLE_CLASS macro twice for the same class. If you want to register previous versions of the class, use the FW_REGISTER_PREV_VERSION_ARCHIVABLE_CLASS macro.
Exception error, calling terminate()
Library: ODFFoundation
File: FWExcImp.cpp
Method: DoTerminate
Explanation: This message can only happen if you're using ODF exceptions, but the problem can happen with either native or ODF exceptions. One way the problem can happen is to throw an exception inside a scope for which there is no active try block. This might happen if you've created a SOM class and you implement one or more methods without a try block (ODF uses try blocks for all of it's SOM entry points).
Why is an autodestruct object of class <classname> being constructed in a bad context? See FWExcImp.cpp for possible causes.
Library: ODFFoundation
File: FWExcImp.cpp
Method: FW_AutoConstructed
Explanation: Possible causes:
1) The autodestruct object is a member of another object which itself is not an autodestruct object. This other object is being allocated via new, not FW_NEW. If so, this is a programmer error. Make the other object's class be autodestruct, and use FW_NEW.
2) This is a static object of a shared library that has just been loaded, and static constructors are being executed. We have attempted to detect this condition and not report it as an error, but may not have eliminated it for all environments. If this is the case, it is not a programming error. You can safely continue execution. Note: if you move this code into an application (as opposed to a shared library), you may need to set FW_gInStaticInit to zero in your main() to inform this subsystem that static initialization is complete.
3) A case similar to 2) is possible. If a static autodestruct object is declared in a function, the compiler is not obligated to initialize it at static initialization time, it can (and should) wait until the function is first called. This case is very difficult to detect (without help from the compiler!). It is not a programming error, and it is safe to continue excecution.
4) You are using threads and did not call FW_Thread_NoteSwitch when threads were switched.
The autodestruct class <classname> is missing an FW_END_CONSTRUCTOR.
Library: ODFFoundation
File: FWExcImp.cpp
Method: FW_AutoDestructed
Explanation: An FW_START_DESTRUCTOR is executing for a class that was constructed without an FW_END_CONSTRUCTOR. Look at every constructor of the class <classname> and make sure it has an FW_END_CONSTRUCTOR. Don't forget that the compiler might generate a copy constructor for you if you haven't declared one. If you declare a class to be autodestruct, the compiler generated copy constructor will not work; you must provide your own definition for the copy constructor. Note that a compiler will also generate a default constructor, but only if you haven't declared any constructors.
An autodestruct class is missing an FW_END_CONSTRUCTOR or FW_START_DESTRUCTOR. Likely candidates: <class1> and <class2> respectively.
Library: ODFFoundation
File: FWExcImp.cpp
Method: FW_AutoDestructed
Explanation: This is similar to the message above, but it is a slightly different case, and harder to pinpoint at runtime. The error is probably a missing FW_START_DESTRUCTOR in class2's destructor, but it may be a missing FW_END_CONSTRUCTOR in one of class1's constructors.
The autodestruct class <classname> is missing an FW_START_DESTRUCTOR
Library: ODFFoundation
File: FWExcImp.cpp
Method: FW_PrivTryBlockContext_Destroy
Explanation: A try block is going out of scope, but an autodestruct object of class <classname> in the try block's scope didn't clean up after itself by calling FW_START_DESTRUCTOR in it's destructor. Find the destructor of the class (classname::~classname) and add the FW_START_DESTRUCTOR macro as the first line of the destructor.
FW_CFixedAllocator: An object of type <classname> has not been deleted properly.
Library: ODFOS
File: FWFixMem.cpp
Method: FW_CFixedAllocator::~FW_CFixedAllocator
Explanation: FW_CInkRep, FW_CStyleRep, FW_CFontRep, and FW_CPatternRep are allocated using a pool allocation scheme. This assertion indicates that on of this object has not been disposed when the allocator is disposed indicating the possibility of a memory leak. This situation can arise if you allocate a FW_CInk, FW_CStyle, FW_CFont or FW_CPattern object on the heap instead that on the stack an forgot to delete it. It could be also that you have one of this object as a field of another object that you are not disposing correctly.
Environment has non-OpenDoc error
Library: ODFOS
File: FWODExce.cpp
Method: FW_GetEvError
Explanation: Don't know what to do, it's a non-OpenDoc error.
FW_CMenuItem::Read should never have been called
Library: ODFOS
File: FWAMnuIt.cpp
Method: FW_CMenuItem::Read
Explanation: ODF is trying to instantiate a FW_CMenuItem which is an abstract base class. This could be the result of an error in your menu resource. In particular you may have left an extra comma after the last menu item (ODFRc doesn't catch this error at compile time).
Trying to set the Facet Part Info of a non-display facet
Library: ODFOS
File: FWFctInf.cpp
Method: FW_SetFacetRefCon
Explanation: FW_SetFacetRefCon was called passing as parameter a facet which is not a display facet. ODF uses the facet's PartInfo field to store information about the device. At part is not allow to set the PartInfo field of a non-display facets.
Failed to load menu resource
Library: ODFOS
File: FWMnuBar.cpp
Method: FW_SetFacetRefCon
Explanation: We use this try-catch block purely to warn about a common mistake. If one forgets to add the resource containing their menus to their project, or passes in the wrong menu id, the above code will throw an exception that probably won't get caught until the SOM entry point from OpenDoc. OpenDoc will display an error dialog that isn't particularly helpful in diagnosing the problem.
Your view or frame is not a FW_MReceiver, or you forgot RTTI macros
Library: ODFFramework
File: FWControl.cpp
Method: FW_CControl::InitializeFromStream
Explanation: If you get this error:
-1- Make sure that the view or frame class you want to link to this control inherits from FW_MReceiver.
-2- Make sure that you use a RTTI macro FW_DEFINE_CLASS_Mx, like:
in FW_MEventHandler::PrivInsert, handler already inserted
Library: ODFFramework
File: FWEventH.cpp
Method: FW_MEventHandler::PrivInsert
Explanation: FW_MEventHandler::AdoptEventHandler() has been called twice with the same event handler to adopt.
Can't call SetLocation on a FW_CFrame
Library: ODFFramework
File: FWFrame.cpp
Method: FW_CFrame::SetLocation
Explanation: You cannot call SetLocation on a view of type FW_CFrame because it is the root view of your frame (i.e. its location is always 0, 0).
The part info resource is missing
Library: ODFFramework
File: FWPart.cpp
Method: FW_CPart::Initialize
Explanation: All ODF parts must have a PartInfo resource. You either forgot to include the resource in your project or passed the wrong ID to the FW_CPart constructor.
Cannot use a ScrollBarScroller here, create a separate content view
Library: ODFFramework
File: FWScrolr.cpp
Method: FW_CScrollBarScroller::PrivCheckFrame
Explanation: ODF doesn't authorize frames to use a scroller with scroll bars in case they don't have a separate content view, because the scroll bars will end up moving with the rest of the frame's content! A frame which is its own content view can only use a basic FW_CScroller object, it can be scrolled with other mechanisms such as hand-scrolling or auto-scrolling.
Failed to load view resource.
Library: ODFFramework
File: FWSView.cpp
Method: FW_CSuperView::CreateSubViewsFromResource
Explanation: We use this try-catch block purely to warn about a common mistake. If one forgets to add the resource containing their views to their project, or passes in the wrong view id, the above code will throw an exception that probably won't get caught until the SOM entry point from OpenDoc. OpenDoc will display an error dialog that isn't particularly helpful in diagnosing the problem.